package view.GUI.turtle;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.geom.Line2D;
import java.util.Vector;
import javax.swing.JViewport;

/**
 *
 * @author Ben
 */
public class Turtle {
    private int[] xPointsPrev, yPointsPrev; //the previous drawing triangle
    private Point position;//the "tail" of the turtle
    private Vector<WalkedLine> drawedLines;
    private boolean drawEnabled;
    private BasicStroke stroke;
    private Color color;
    private int angle;
    private final int RADIUS = 25; // the radius of the circle you could draw around the turtle
    private boolean visible;
    private int delay = 1000;

    public Turtle() {
        init();
    }

    public void setDelay(int delay) {
        this.delay = delay;
    }

    private Point getCenter(){
       Rectangle rect = ((JViewport)controller.StdDraw.getInstance().getPanel().getParent()).getViewRect();
       return new Point((int)(rect.getX() + rect.getWidth()/2),
                        (int)(rect.getY() + rect.getHeight()/2));
    }

    public void init(){
        this.angle = -90; //north
        this.drawedLines = new Vector<WalkedLine>();
        this.xPointsPrev = null;
        this.yPointsPrev = null;
        this.stroke = new BasicStroke(1);
        this.color = Color.BLACK;
        this.drawEnabled= true;
        this.visible = true;
    }

    public void reset(){
        this.position = getCenter();
        init();
        Graphics g = controller.StdDraw.getInstance().getGraphics();
        g.clearRect(0, 0, (int)position.getX()*2, (int)position.getY()*2);
    }

    public void setCentered(){
        this.position = getCenter();
        draw();
    }

    public void setOrientation(String orientation) {
        if(orientation.equals("East")){
            angle = 0;
        }else if(orientation.equals("South")){
            angle = -270;
        }else if(orientation.equals("West")){
            angle = -180;
        }else angle = -90;//north
        draw();
    }

    public void setDrawEnabled(boolean drawEnabled){
        this.drawEnabled = drawEnabled;
    }

    public void setPenWidth(int penWidth){
        this.stroke = new BasicStroke(penWidth);
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public void setVisible(boolean visible){
        this.visible = visible;
    }

    public void draw(){
        try{
            Robot r = new Robot();
            r.delay(delay);
        }catch(Exception e){
            e.printStackTrace();
        }

        Graphics g = controller.StdDraw.getInstance().getGraphics();
        Dimension dim = controller.StdDraw.getInstance().getPanel().getSize();
        g.clearRect(0, 0, dim.width, dim.height);
        Color c = g.getColor();//backup
        //clear the previous turtle
        /*if(xPointsPrev != null){
            g.setColor(Color.WHITE);
            g.fillPolygon(xPointsPrev,yPointsPrev,4);
        }*/

        //draw the turtle
        if(visible){
            Point leftFoot = getPointRelativeToPosition(-90, RADIUS);
            Point rightFoot = getPointRelativeToPosition(90, RADIUS);
            Point nose = getPointRelativeToPosition(0, RADIUS);
            int[] xPoints = new int[]{(int)nose.getX(),(int)leftFoot.getX(),(int)rightFoot.getX(),(int)nose.getX()};
            int[] yPoints = new int[]{(int)nose.getY(),(int)leftFoot.getY(),(int)rightFoot.getY(),(int)nose.getY()};
            g.setColor(Color.GREEN);
            g.fillPolygon(xPoints, yPoints, 4);
            g.setColor(c);
            xPointsPrev = xPoints;
            yPointsPrev = yPoints;
        }
        //draw all the drawed lines
        for(WalkedLine linew: drawedLines){
            Line2D.Double line = linew.getLine();
            ((Graphics2D)g).setStroke(linew.getStroke());
            g.setColor(linew.getColor());
            g.drawLine((int)line.getX1(), (int)line.getY1(), (int)line.getX2(), (int)line.getY2());
        }
    }

    private Point getPointRelativeToPosition(int angle, double radius){
        double radians = Math.toRadians(this.angle + angle);
        double deltaX = radius * Math.cos(radians);
        double deltaY = radius * Math.sin(radians);
        Point result = new Point((int)(position.getX() + deltaX), (int)(position.getY() + deltaY));
        return result;
    }

    public void move(int units){
        Point oldPosition = (Point)position.clone();
        position = getPointRelativeToPosition(0, units);
        if(drawEnabled){
            WalkedLine lineStr = new WalkedLine(new Line2D.Double(oldPosition, position),stroke,color);
            drawedLines.add(lineStr);
        }
        draw();
    }

    public void turn(int degrees, boolean left){
      if(left){
        angle -= degrees;
      }else{
        angle += degrees;
      }
      angle %= 360;
      draw();
    }

    public Point getPosition() {
        return position;
    }

    public void setPosition(Point position) {
        this.position = position;
    }
    
}
